package cn.hzc.fortess.system.controller;

import cn.hzc.fortess.core.common.ResponseData;
import cn.hzc.fortess.core.common.annotion.RequestPermission;
import cn.hzc.fortess.core.common.constant.Const;
import cn.hzc.fortess.core.common.BizErrorEnum;
import cn.hzc.fortess.core.common.exception.ServiceException;
import cn.hzc.fortess.core.shiro.ShiroKit;
import cn.hzc.fortess.system.common.EnableStatus;
import cn.hzc.fortess.system.common.IHelper;
import cn.hzc.fortess.system.common.ResourceScope;
import com.google.common.collect.Lists;
import cn.hzc.fortess.system.common.MenuType;
import cn.hzc.fortess.system.entity.Menu;
import cn.hzc.fortess.system.node.ZTreeNode;
import cn.hzc.fortess.system.page.Pagination;
import cn.hzc.fortess.system.search.MenuSearch;
import cn.hzc.fortess.system.service.MenuService;
import cn.hzc.fortess.system.service.ProjectService;
import cn.hzc.fortess.system.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(tags = {"菜单管理"})
@Controller
@RequestMapping("/sam/menu")
public class MenuController extends BaseController {

    @Autowired
    private MenuService menuService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private ProjectService projectService;


    @ApiIgnore
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String index() {
        setAttr("projects", projectService.getUserProject());
        return buildToView("index.html");
    }

    @ApiIgnore
    @RequestMapping(value = "/add/{id}")
    public String add(@PathVariable(value = "id", required = true) Integer parentId) {
        Menu menu = new Menu();
        menu.setPid(parentId);
        Menu parentMenu = menuService.getById(parentId);
        if (Objects.equals(MenuType.BUTTON.getType(), parentMenu.getResourceType())) {
            throw new ServiceException(BizErrorEnum.MENU_BUTTON_ADDSUB);
        }
        menu.setProjectId(parentMenu.getProjectId());

        menu.setResourceType(MenuType.MENU.getType());//菜单
        menu.setResourcePath("/");
        menu.setIdx(100);
        menu.setViewStatus(Const.YES);
        menu.setStatus(EnableStatus.ENABLE.getStatus());
        menu.setLevels(parentMenu.getLevels() + 1);
        menu.setResourceScope(ResourceScope.PUBLIC_READ_WRITE.getCode());
        setAttr("menu", menu);
        return buildToView("form.html");
    }

    @ApiOperation("创建菜单")
    @RequestMapping(value = "/add.json", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:menu:add")
    public ResponseData create(Menu menu) {
        this.menuService.add(menu);
        return ResponseData.success();
    }


    @ApiIgnore
    @RequestMapping(value = "/edit/{id}")
    public String menuEdit(@PathVariable(value = "id", required = true) Integer menuId) {
        Menu menu = this.menuService.getById(menuId);
        Integer scope = menuService.getResourceScopeById(menuId);
        menu.setResourceScope(scope);
        setAttr("menu", menu);
        return buildToView("form.html");
    }

    @ApiOperation("编辑菜单")
    @RequestMapping(value = "/edit.json", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:menu:edit")
    public ResponseData edit(Menu menu) {
        this.menuService.update(menu);

        return ResponseData.success();
    }

    @ApiOperation("删除菜单")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    @RequestPermission("sam:menu:delete")
    public ResponseData delete(@PathVariable(value = "id", required = true) Integer menuId) {
        Menu menu = menuService.getById(menuId);
        if (menu.getLevels() == 1) {
            throw new ServiceException(BizErrorEnum.CANT_DELETE_MENU);
        }

        this.menuService.delete(menuId);
        return ResponseData.success();
    }

    @ApiOperation("获取菜单列表")
    @RequestPermission("sam:menu:list")
    @RequestMapping(value = "/listTree", method = RequestMethod.GET)
    @ResponseBody
    public Object page(MenuSearch search) {
        final boolean isAdminstrator = ShiroKit.getUser().isAdministrator();
        if (!isAdminstrator) {
            search.setProjectIds(projectService.getUserProjectIds());
        } else if (isAdminstrator && search.getProjectId() == null) {
            //超级管理员查询时缩小范围
            search.setProjectId(Const.SAM_PROJECT_ID);

        }
        List<Menu> menus = this.menuService.getMenuList(search);

        menus.parallelStream().forEach(menu -> {

            if (!Objects.equals(Const.SAM_PROJECT_ID, menu.getProjectId())) {
                menu.setResourceUrl("/sam/resource/" + menu.getId());
            }
        });
        Pagination result = new Pagination();
        result.setData(menus);
        return result;
    }

    @ApiOperation(value = "获取菜单树状列表", httpMethod = "POST")
    @RequestPermission("sam:menu:list")
    @RequestMapping(value = "/selectMenuTreeList", method = RequestMethod.POST)
    @ResponseBody
    public List<ZTreeNode> menuTree() {
        List<Integer> projectIds = null;
        if (!ShiroKit.getUser().isAdministrator()) {
            projectIds = (projectService.getUserProjectIds());
        }
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList(projectIds);
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
//


    /**
     * 角色授权的菜单树
     */
    @ApiOperation("获取角色授权的菜单树")
    @RequestPermission("sam:role:auth")
    @RequestMapping(value = "/menuTreeListByRoleId/{roleId}", method = RequestMethod.POST)
    @ResponseBody
    public List<ZTreeNode> menuTreeByRole(@PathVariable(value = "roleId") Integer roleId) {

        //查询所有可用于授权的menu
        final Integer projectId = roleService.getById(roleId).getProjectId();

        List<Menu> menus = this.menuService.getEnableAuthMenus(projectId);

        final List<Integer> roleMenuIds = menuService.getMenuIdListByRole(roleId);

        List<ZTreeNode> nodes = Lists.newArrayList();

        if (Objects.equals(projectId, Const.SAM_PROJECT_ID)) {
            ZTreeNode root = ZTreeNode.createParent();
            root.setName(Const.SAM_RPOJECT_NAME);
            root.setChecked(false);
            nodes.add(root);
        }
        menus.stream().forEach(menu -> {
            final ZTreeNode zTreeNode = new ZTreeNode();
            zTreeNode.setChecked(roleMenuIds.contains(menu.getId()));
            zTreeNode.setId(Long.parseLong(menu.getId().toString()));
            zTreeNode.setName(menu.getResourceName());
            zTreeNode.setOpen(true);
            zTreeNode.setPId(Long.parseLong(menu.getParentId().toString()));


            nodes.add(zTreeNode);
        });
        return nodes;

    }

    @Override
    protected String moduleName() {
        return "menu";
    }
}
